package p.ithorns.framework.feign.enhance;

import org.springframework.aop.framework.AopProxyUtils;
import org.springframework.aop.support.AopUtils;
import org.springframework.beans.factory.FactoryBean;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.util.ClassUtils;

import java.lang.reflect.Proxy;
import java.util.Set;


/**
 * @author Ht.L
 */
public class FeignSvcFactoryBean<T> implements FactoryBean<T> {

    private final Class<?> type;

    public final Object instance;


    public FeignSvcFactoryBean(Class<?> type, Object instance) {
        this.type = type;
        this.instance = instance;
    }

    @Override
    public T getObject() {
        // return createCglibProxy(target);
        return (T) createJdkProxy(type, instance);

    }

    @Override
    public Class<?> getObjectType() {
        return instance.getClass();
    }

    private Object createJdkProxy(Class<?> type, Object instance) {
        return Proxy.newProxyInstance(
                type.getClassLoader(),
                new Class<?>[]{type, FeignController.class},
                new FeignSvcJdkProxy(instance)
        );
    }

    private <T> T createCglibProxy(Object target) {
        Enhancer enhancer = new Enhancer();

        boolean cglibProxy = AopUtils.isCglibProxy(target);
        Object singletonTarget = AopProxyUtils.getSingletonTarget(target);
        Class<?> targetClass =  AopUtils.getTargetClass(target);

        // 设置类加载
        enhancer.setClassLoader(targetClass.getClassLoader());

        // 设置被代理类
        // enhancer.setSuperclass(targetClass);
        Set<Class<?>> interfaces = ClassUtils.getAllInterfacesForClassAsSet(targetClass);
        interfaces.add(FeignController.class);
        // new Class[]{targetClass, FeignController.class}
        enhancer.setInterfaces(interfaces.toArray(new Class[0]));

        // 设置方法拦截器
        enhancer.setCallback(new FeignSvcCglibProxy(target));
        // 创建代理类
        return (T) enhancer.create();
    }

}